package com.erp.erp_ui.Cost.Service;

import com.erp.enums.ModuleTypeEnum;
import com.erp.erp_entitys.Cost.entity.CostEntity;
import com.erp.erp_entitys.Cost.entity.CostPaymentEntity;
import com.erp.erp_entitys.Cost.req.CostAnnexReq;
import com.erp.erp_entitys.Cost.req.CostPaymentReq;
import com.erp.erp_entitys.Cost.req.ModifyAndInsertCostReq2;
import com.erp.erp_entitys.warehouse.entity.AnnexEntity;
import com.erp.erp_entitys.warehouse.entity.TempAnnexEntity;
import com.erp.erp_servers.Cost.CostPaymentService;
import com.erp.erp_servers.Cost.CostService;
import com.erp.erp_servers.warehouse.IAnnexService;
import com.erp.erp_servers.warehouse.ITempAnnexService;
import com.erp.utils.DateUtils;
import com.erp.utils.R;
import com.erp.utils.ResultStatusEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zjk
 * @version 1.0
 * @description 费用实付接口
 * @date 2021/1/1/001 21:48
 */
@Service
public class CostPaymentAllService {
    private final CostService costService;


    private final CostPaymentService costPaymentService;
    /**
     * 附件接口
     */
    private final IAnnexService annexService;
    /**
     * 临时附件接口
     */
    private final ITempAnnexService tempAnnexService;

    @Autowired
    public CostPaymentAllService(CostService costService, CostPaymentService costPaymentService, IAnnexService annexService, ITempAnnexService tempAnnexService) {
        this.costService = costService;
        this.costPaymentService = costPaymentService;
        this.annexService = annexService;
        this.tempAnnexService = tempAnnexService;
    }

    /**
     * 添加费用实付，附件
     * @param costReq
     * @return  返回信息
     */
    @Transactional(rollbackFor = Exception.class)
    public R addCostPayment(ModifyAndInsertCostReq2 costReq) {
            //获取费用付款集合
            List<CostPaymentReq> costPaymentReqList=costReq.getCostPaymentReqList();
            //获取旧费用实付集合
            List<CostPaymentEntity> oldPayments=costPaymentService.findAllByCostCode(costReq.getCode());
            //获取旧id集合
            List<Integer> oldIds=oldPayments.stream().map(p -> p.getId()).collect(Collectors.toList());

            //获取新id集合
            List<Integer> newIds=costPaymentReqList.stream().map(p -> p.getId()).collect(Collectors.toList());

            //获得删除的元素
            if (newIds.size()!=0){
                oldIds.removeAll(newIds);
            }
            //修改删除元素的状态为无效
            if (oldIds.size()!=0){
                costPaymentService.updateCostPaymentInvalid(0, oldIds);
            }

            //新的费用实付金额合计
            BigDecimal tempBig=new BigDecimal(0);
            //最大实付日期
            Date maxDate=null;

            if(costPaymentReqList.size()!=0){
                //获取日期集合
                List<Date> dateList=costPaymentReqList.stream().map(p->p.getCreateTime()).collect(Collectors.toList());
                maxDate= Collections.max(dateList);

                //添加传过来的参数
                for (CostPaymentReq newPayment:  costPaymentReqList) {
                    CostPaymentEntity costPayment=new CostPaymentEntity();
                    BeanUtils.copyProperties(newPayment,costPayment);
                    if (newPayment.getId() == null){
                        //费用实付新增
                        int numPayment=costPaymentService.insertCostPayment(costPayment);
                        if (numPayment!=1){
                            return R.buildError(ResultStatusEnum.PARAMETER_ERROR);
                        }
                    }else {
                        costPaymentService.updateCostPayment(costPayment);
                    }
                    //费用实付金额
                    BigDecimal newTotalCost=newPayment.getTotalCost();
                    tempBig=tempBig.add(newTotalCost);
                }
            }

            CostEntity costEntity=costService.selectByPrimaryKey(costReq.getCode());
            //费用总金额
            BigDecimal totalAmount=costEntity.getTotalAmount();
            //费用主信息存在，并且新增的费用实付总金额不大于费用总金额
            if (costEntity!=null && tempBig.compareTo(totalAmount)!=1){
                //修改费用主表中的的实付金额
                costService.updateCostAndTime(tempBig,maxDate,costReq.getCode());
            }


            List<CostAnnexReq> newAnnexReqs=costReq.getAnnexReqs();
            CostEntity tempCost=costService.selectByPrimaryKey(costReq.getCode());
            Integer costId=tempCost.getId();
            //添加附件信息
            boolean flag = addAnnex(newAnnexReqs, costId, costReq.getOperatorName(), costReq.getOperatorCode());
            //删除临时附件信息
            deleteTempAnnex(newAnnexReqs);
            if(!flag){
                return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
            }
        return R.build(ResultStatusEnum.SUCCESS);

    }

    /**
     * 批量处理临时附件信息，将临时附件设置为失效
     * @param annexReqs
     */
    public void deleteTempAnnex(List<CostAnnexReq> annexReqs){
        //没有附件
        if(CollectionUtils.isEmpty(annexReqs)){
            return;
        }
        //存在附件
        for(CostAnnexReq annex : annexReqs){
            if(null != annex.getNews()){
                //旧附件,不用修改
                continue;
            }
            TempAnnexEntity tempAnnex = new TempAnnexEntity();
            //设置临时附件id
            tempAnnex.setId(annex.getId());
            //设置修改时间
            tempAnnex.setUpdateTime(new Date());
            //将附件设置为失效
            tempAnnex.setValid(0);
            tempAnnexService.update(tempAnnex);
        }

    }
    /**
     * 附件新增
     * @param annexReqs 附件信息集合
     * @param costId 费用id
     * @param operator 操作人
     * @param operatorNo 操作人编码
     * @return 是否新增成功(true:成功 false:失败 )
     */
    public boolean addAnnex(List<CostAnnexReq> annexReqs, Integer costId, String operator, String operatorNo) {
        //新增,修改附件明细

        //获取新附件id集合
        List<Integer> newIds = annexReqs.stream().map(p -> p.getId()).collect(Collectors.toList());
        //获取旧的附件id集合开始
        //通过费用id获取旧附件附件信息
        AnnexEntity annex = new AnnexEntity();
        annex.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_COST.getId());
        annex.setParentId(costId);
        //获取旧附件信息,并得到旧附件ID的集合
        List<Integer> oldIds = annexService.queryAll(annex).stream().map(p -> p.getId()).collect(Collectors.toList());

        //获得删除的附件
        if (newIds.size()>0){
            oldIds.removeAll(newIds);
        }
        //修改附件的状态为无效
        if (oldIds.size()>0){
            costService.updateAnnexValid(oldIds,0);
        }

        //循环添加附件
        return foreachAnnexReq(annexReqs, costId,operator,operatorNo);

    }

    /**
     * 循环添加附件的方法
     * @param annexReqs
     * @param costId
     * @param operator
     * @param operatorNo
     * @return false添加失败，true：添加成功
     */
    public boolean foreachAnnexReq(List<CostAnnexReq> annexReqs, Integer costId, String operator, String operatorNo){
        try {
            boolean flag=true;
            //添加费用明细信息
            for (CostAnnexReq annexReq:  annexReqs) {
                //旧附件的news属性为0，新附件的news属性为null
                if (annexReq.getNews()==null){
                    AnnexEntity annex = new AnnexEntity();
                    BeanUtils.copyProperties(annexReq, annex);
                    //设置关联模块id
                    annex.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_COST.getId());
                    //设置关联模块父id
                    annex.setParentId(costId);
                    //设置上传时间
                    annex.setUploadTime(DateUtils.convertStringToDate(annexReq.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
                    //设置修改时间
                    annex.setUpdateTime(new Date());
                    //设置操作人
                    annex.setOperator(operator);
                    //设置操作人编码
                    annex.setOperatorNo(operatorNo);
                    //设置数据有效
                    annex.setValid(1);

                    Integer num= annexService.insert(annex);
                    if (num>0){
                        flag= true;
                    }else{
                        flag=false;
                    }
                }
            }
            return flag;
        } catch (ParseException e) {
            e.printStackTrace();
            return false;
        }
    }
}
